package sel.me.popular.library.learning.quasar;

import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.strands.SuspendableCallable;

import java.lang.management.ManagementFactory;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * VM option:
 * -Xms1024m -Xmx1024m -javaagent:C:\Users\yuningsel\.m2\repository\co\paralleluniverse\quasar-core\0.7.9\quasar-core-0.7.9-jdk8.jar
 *
 *  JVM线程中断的条件只有两个，一个是抛异常，另外一个就是return。
 *  这里Quasar就是通过抛异常的方式来达到的，所以你会看到我上面的代码会抛出SuspendExecution
 *
 * 协程的方式更多用来做I/O密集型的操作。计算密集型的还是使用线程更加合理。
 *
 * @author shenenlu 2021年06月23日 下午13:51:11
 * https://www.cnblogs.com/ll409546297/p/10945119.html
 */
public class QuasarMemoryUse {

    private static final int COUNT = 700000;

    private static final int SLEEP_TIME = 40 * 1000;

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
        System.out.println(pid);
        //        threadMemoryUse();
        fiberMemoryUse();
    }

    private static void fiberMemoryUse() throws InterruptedException, ExecutionException {
        //使用阻塞队列来获取结果。
        LinkedBlockingQueue<Fiber<Integer>> fiberQueue = new LinkedBlockingQueue<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < COUNT; i++) {
            int finalI = i;
            //这里的Fiber有点像Callable,可以返回数据
            Fiber<Integer> fiber = new Fiber<>((SuspendableCallable<Integer>) () -> {
                //这里用于测试内存占用量
                Fiber.sleep(SLEEP_TIME);
//                Fiber.sleep(1000);
                System.out.println("in-" + finalI + "-" + LocalDateTime.now().format(formatter));
                return finalI;
            });
            //开始执行
            fiber.start();
            //加入队列
            fiberQueue.add(fiber);
        }
        while (true) {
            //阻塞
            Fiber<Integer> fiber = fiberQueue.take();
            System.out.println("out-" + fiber.get() + "-" + LocalDateTime.now().format(formatter));
        }

    }

//    private static void threadMemoryUse() {
//
//        for (int i = 0; i < COUNT; i++) {
//            new Thread(() -> {
//                try {
//                    Thread.sleep(SLEEP_TIME);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }).start();
//        }
//
//    }


}
